package com.cyx.demo1_zhs.controller;

import com.cyx.demo1_zhs.dto.ResultDTO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/zhs")
public class ZhsController {

    @PostMapping("/cacl") // 必须用POST接收@RequestBody
    public String executeJar(@RequestBody ResultDTO resultDTO) {
        // jar 包所在的路径 这里是绝对路径
        String jarPath = resultDTO.getPath();
        // 执行java -jar 所需的参数
        List<Integer> args = resultDTO.getArgs();

        // 将Integer参数转为String数组
        String[] params = args.stream()
                .map(String::valueOf)
                .toArray(String[]::new);

        // 创建操作系统进程来执行 java -jar 命令
        ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", jarPath);
        // 将接收到的参数转换为 List<String> 的列表
        processBuilder.command().addAll(Arrays.asList(params)); // 添加参数

        try {
            // 启动由 ProcessBuilder 配置的外部进程，process 用来管理该子进程
            Process process = processBuilder.start();

            // 使用多线程读取输出流和错误流（避免阻塞）
            StringBuilder output = new StringBuilder();
            StringBuilder error = new StringBuilder();

            // try(... = ...) 确保资源在代码块结束后自动关闭
            // BufferedReader 对字符流进行缓冲，提高读取效率，支持逐行读取 readLine()
            // InputStreamReader 将字节流转换为字符流，支持按字符读取
            // process.getInputStream() 获取子进程的输出流，返回一个 InputStream(字节流)
            Thread outputThread = new Thread(() -> {
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(process.getInputStream()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        output.append(line).append("\n");
                    }
                } catch (Exception e) {
                    error.append("Error reading output: ").append(e.getMessage());
                }
            });

            Thread errorThread = new Thread(() -> {
                // try(... = ...) 确保资源在代码块结束后自动关闭
                // BufferedReader 对字符流进行缓冲，提高读取效率，支持逐行读取 readLine()
                // InputStreamReader 将字节流转换为字符流，支持按字符读取
                // process.getErrorStream() 获取子进程的错误流，返回一个 InputStream(字节流)
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(process.getErrorStream()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        error.append(line).append("\n");
                    }
                } catch (Exception e) {
                    error.append("Error reading error stream: ").append(e.getMessage());
                }
            });

            // 启动线程
            // 读取输出流的线程
            outputThread.start();
            // 读取错误流的线程
            errorThread.start();

            // 等待进程结束
            // 主线程(main 方法)进行阻塞等待，直到 process 子进程执行结束
            int exitCode = process.waitFor();
            // 主线程暂停执行进行阻塞等待，直到 outputThread 和 errorThread 线程执行结束
            outputThread.join();
            errorThread.join();

            // 组合结果
            String result = "Exit Code: " + exitCode + "\n";
            if (error.length() > 0) {
                result += "Error Output:\n" + error;
            } else {
                result += "Output:\n" + output;
            }

            return result;

        } catch (Exception e) {
            return "Failed to execute JAR: " + e.getMessage();
        }
    }
}